package com.dotstone.chipism.bean;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.Random;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;

import com.dotstone.chipism.util.ConvertUtil;
import com.dotstone.chipism.util.DeviceManager;
//import org.json.JSONException;
//import org.json.JSONObject;

public class MySocket1 {
	private String tcpIp;
	private int tcpPort;
	private boolean localSuccess = false;
	private boolean remoteSuccess = false;// 是否远程连接成功
	private boolean isStopByUser = false;
	private boolean stop = false;
	private String mac = "";
	private String manufacturer = "";
	private String productId = "";
	private int position;
	private Context c;
	private Socket socket_local;
	private InputStream in_local;// 本地socket输入流
	private OutputStream out_local;// 本地socket输出流
	private boolean receiving = false;
	private StringBuffer sb = new StringBuffer();
	private RecDataCallBackListener_Bind listener_Bind;
	private RecDataCallBackListener_Heart listener_Heart;
	private RecDataCallBackListener_Serach listener_Serach;
	private RecDataCallBackListener_Alarm listener_Alarm;
	private RecDataCallBackListener_Study listener_Study;
	private RecDataCallBackListener_TempHumity listener_TempHumity;
	private RecDataCallBackListener_Record listener_Record;
	private RecDataCallBackListener_Update listener_Update;
	private RecDataCallBackListener_Version listener_Version;
	private RecDataCallBackListener_Time listener_Time;
	private OnConnectSuccessListener listener_ConnectSuccess;
	private OnBindFailListener listener_fail;
	public static String user_id;
	private String command_local;
	private long sendTime;
	private LinkedList<String> queue_local = new LinkedList<String>();
	private String mCurrenCmd;
	private String heartBeatCmd;
	private String recClass;
	private String callBackData = "";
	private long sendHeartBeatTime;
	private long receiveHeartBeatTime;
	private boolean isNotReceiving = true;
	private String wmy = "MQTTPubClient";
	private int mSDKVersion;
	private DatagramSocket udpclient;
	// private byte[] openByteL = new byte[] { 0x51, 0x10, (byte) 0x00 };
	// private byte[] closeByteL = new byte[] { 0x51, 0x10, (byte) 0xff };
	private byte[] openByteR = new byte[] { 0x52, 0x10, (byte) 0x00 };
	private byte[] closeByteR = new byte[] { 0x52, 0x10, (byte) 0xff };
	private String openByteL = "{\"cmd\":32,\"src\":20,\"dest\":10,\"dir\":1,\"deviceId\":\"10000\",\"userId\":\"10000\",\"requestTime\":342152345,\"data\":{\"switch\":1}}";
	private String closeByteL = "{\"cmd\":32,\"src\":20,\"dest\":10,\"dir\":1,\"deviceId\":\"10000\",\"userId\":\"10000\",\"requestTime\":342152345,\"data\":{\"switch\":0}}";

	public boolean isLocalSuccess() {
		return localSuccess;
	}

	public void setLocalSuccess(boolean localSuccess) {
		this.localSuccess = localSuccess;
	}

	public String getMac() {
		return mac;
	}

	public boolean isStop() {
		return stop;
	}

	public void setStop(boolean stop) {
		Log.i("wmy", "设置stop为" + this.stop);
		this.stop = stop;
		Log.i("wmy", "设置stop为" + this.stop);
	}

	public void setMac(String mac) {
		this.mac = mac;
	}

	public long getSendHeartBeatTime() {
		return sendHeartBeatTime;
	}

	public void setSendHeartBeatTime(long sendHeartBeatTime) {
		Log.i("wmy", "设置发送时间");
		this.sendHeartBeatTime = sendHeartBeatTime;
	}

	public long getReceiveHeartBeatTime() {
		return receiveHeartBeatTime;
	}

	public void setReceiveHeartBeatTime(long receiveHeartBeatTime) {
		Log.i("wmy", "设置接收时间");
		this.receiveHeartBeatTime = receiveHeartBeatTime;
	}

	public boolean isNotReceiving() {
		return isNotReceiving;
	}

	public void setNotReceiving(boolean isNotReceiving) {
		this.isNotReceiving = isNotReceiving;
		if (isNotReceiving) {
			receiveHeartBeatTime = System.currentTimeMillis();
		}
	}

	public MySocket1(WlanInfo wlanInfo, final Context c) {

		this.mac = wlanInfo.getMac();
		this.manufacturer = wlanInfo.getManufacturer();
		this.productId = wlanInfo.getProductId();
		this.position = wlanInfo.getPosition();
		this.c = c;
		mSDKVersion = DeviceManager.getInstance().getmSDKVersion();
		// startMQTTClient();
		Log.e("wmy", "创建一个socket111" + mac);
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				startLocalTcpClient(c);
				startCommandThread();
				startHeartBeat();
				sendHeartBeatTime = System.currentTimeMillis();
				receiveHeartBeatTime = System.currentTimeMillis();
				// startFailListen
			}
		}).start();
	}

	// 需要建立一个发送方法，如果发送失败了，则将发送失败的消息放入缓存队列，待连接成功后发送
	// 有些消息在发送时 界面已经做出了响应，如开关，所以需要保证消息是能够被发送的 要对发送进行检测，如果发送失败 会触发异常
	// 则检查触发异常时当前的消息是否已经发送成功，如不成功，待连接成功后重新发送
	// 该消息队列里的消息在5秒内自动清零

	private void startLocalTcpClient(final Context c) {
		isStopByUser = false;
		new Thread() {
			public void run() {
				while (!stop) {
					Log.i("wmy", "stop = " + stop);
					try {
						if (localSuccess) {
							sleep(2000);
							continue;
						}

						if (mac.equals("")) {
							Log.i("wmy", "mac为空");
							sleep(3000);
							continue;
						}
						int max = 9999;
						int min = 1000;
						Random random = new Random();
						int s = random.nextInt(max) % (max - min + 1) + min;
						udpclient = new DatagramSocket(s);
						final String sendStr = ConvertUtil.getInstance()
								.convertUDPCmd(mac.toUpperCase(), manufacturer,
										productId);
						byte[] sendBuf = sendStr.getBytes();
						InetAddress addr = InetAddress
								.getByName("255.255.255.255");
						final DatagramPacket sendPacket = new DatagramPacket(
								sendBuf, sendBuf.length, addr, 3000);
						new Thread(new Runnable() {
							@Override
							public void run() {
								// TODO Auto-generated method stub
								int count = 0;
								while ((!localSuccess) && count < 20) {
									// // 发送数据
									try {
										if (udpclient != null) {
											udpclient.send(sendPacket);
											udpclient.send(sendPacket);
											udpclient.send(sendPacket);
											Thread.sleep(1000);
											Log.i("wmy", "发送广播  = " + count
													+ " " + sendStr);
										}
									} catch (InterruptedException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									} catch (IOException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
									count++;
								}
							}
						}).start();

						boolean udpFlag = true;

						while (udpFlag) {
							// client.send(sendPacket);
							byte[] recvBuf = new byte[2048];
							// Log.i("", msg)
							DatagramPacket recvPacket = new DatagramPacket(
									recvBuf, recvBuf.length);
							// 接收数据
							udpclient.receive(recvPacket);
							String recvStr = new String(recvPacket.getData(),
									0, recvPacket.getLength());
							tcpIp = recvPacket.getAddress().toString()
									.substring(1);
							tcpPort = parseTCPPort(recvStr.replace("\t", ""));
							recvStr = "";
							socket_local = new Socket();
							if (tcpPort == 0) {
								tcpPort = 5000;
							}
							socket_local.connect(new InetSocketAddress(tcpIp,
									tcpPort), 5000);
							socket_local.setTcpNoDelay(true);
							// socket_local.se
							in_local = socket_local.getInputStream();
							out_local = socket_local.getOutputStream();
							Log.i("wmy", mac + " local connect = "
									+ socket_local.isConnected());
							udpclient.close();
							// udpclient = null;
							localSuccess = true;
							udpclient = null;
							if (listener_ConnectSuccess != null) {
								listener_ConnectSuccess.onReceiveData(mac);
							}
							receiveHeartBeatTime = System.currentTimeMillis();
							recvPacket = null;
							tcpIp = "";
							tcpPort = 0;
							// recvBuf= null
							recvBuf = null;
							udpFlag = false;
							BufferedReader br = null;
							// br = new BufferedReader(new
							// InputStreamReader(in_local));
							br = new BufferedReader(new InputStreamReader(
									in_local, "ASCII"));
							receiving = true;
							while (socket_local.isConnected()) {
								if (br != null) {
									char[] cha = new char[2048];
									int len = br.read(cha);
									if (len < 2048&& !(len < 0 || len > cha.length)) {
										String str = new String(cha, 0, len);

										// 收到数据后，先进行解析，获取cmd值，如果属于什么类型的回调，就放入什么类型的接口
										if (str != null) {
											str.replace("\t", "");
											parseData(str);
										}
									}
								}
							}
						}
					} catch (UnknownHostException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						localSuccess = false;
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						localSuccess = false;
						// stopLocalTcpClient1();
						Log.i("wmy", "socket11111 " + mac + " 230局域网连接被中断错误");
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						Log.i("wmy", "socket " + mac + " 234局域网连接被中断错误");
						localSuccess = false;
					}

					try {
						sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
						Log.i("wmy", "socket " + mac + " 局域网连接被中断错误");
						localSuccess = false;
					}
				}

			};
		}.start();
	}

	public void startHeartBeat() {
		// heartBeatCmd = transHeartCmd();
		heartBeatCmd = ConvertUtil.getInstance().convertHeartCmd();
		new Thread() {
			public void run() {
				while (!stop) {
					try {
						if (isNotReceiving) {
							// sendMqttData(heartBeatCmd);
							if (localSuccess) {
								if (socket_local.isConnected()) {
									queue_local.add(heartBeatCmd);
									mCurrenCmd = "";
									sendHeartBeatTime = System
											.currentTimeMillis();
									// Log.i
									if (sendHeartBeatTime
											- receiveHeartBeatTime > 11 * 1000) {
										Log.i("wmy",
												mac
														+ "超时！！"
														+ (sendHeartBeatTime - receiveHeartBeatTime));
										localSuccess = false;
									}
								}
								Thread.sleep(9 * 1000);
							} else {
								Thread.sleep(5 * 1000);
							}
						} else {
							Thread.sleep(5 * 1000);
						}
					} catch (Exception e) {
						// TODO: handle exception

					}
				}
			}
		}.start();
	}

	public void startCommandThread() {
		new Thread() {
			public void run() {
				while (!stop) {
					try {
						if (queue_local.size() > 0) {
							if (localSuccess) {
								command_local = queue_local.removeFirst();
								out_local.write(command_local.getBytes());
								out_local.flush();
							}
						}
						sleep(300);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			};
		}.start();
	}

	public void sendCmdNeedRec(String cmd) {
		if (localSuccess) {
			if (socket_local.isConnected()) {
				try {
					out_local.write(cmd.getBytes());
					out_local.flush();
					mCurrenCmd = "";
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					localSuccess = false;
				}
			}
		}
	}

	public void sendWlan2Data(boolean power) {
		Log.i("wmy", mac + " " + power);
		String log = "buflen:" + 3;
		if (power) {
			try {
				if (localSuccess) {
					if (mSDKVersion > 23) {
						new Thread(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								try {
									try {
										Thread.sleep(100);
										Log.i("wmy", "开" + openByteL);
										out_local.write(openByteL.getBytes());
										out_local.flush();
									} catch (InterruptedException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						}).start();
					} else {
						Log.i("wmy", "开" + openByteL);
						out_local.write(openByteL.getBytes());
						out_local.flush();
					}
				} else if (remoteSuccess) {

				}
			} catch (Exception e) {
				stopLocalTcpClient();
				e.printStackTrace();
			}
		} else {
			try {
				if (localSuccess) {
					if (mSDKVersion > 23) {
						new Thread(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								try {
									try {
										Thread.sleep(100);
										Log.i("wmy", "关" + closeByteL);
										out_local.write(closeByteL.getBytes());
										out_local.flush();
									} catch (InterruptedException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						}).start();
					} else {
						Log.i("wmy", "关" + closeByteL);
						out_local.write(closeByteL.getBytes());
						out_local.flush();
					}
				} else if (remoteSuccess) {

				}
			} catch (Exception e) {
				stopLocalTcpClient();
				e.printStackTrace();
			}
		}
	}

	public void sendMqttData(final String cmd) {
		Log.d("send", "发送cmd" + cmd);
		if (localSuccess) {
			if (socket_local.isConnected()) {
				if (cmd != null && out_local != null) {
					if (mSDKVersion > 23) {
						new Thread(new Runnable() {

							@Override
							public void run() {
								// TODO Auto-generated method stub
								try {
									Thread.sleep(100);
									out_local.write(cmd.getBytes());
									out_local.flush();
								} catch (InterruptedException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						}).start();
						mCurrenCmd = "";
					} else {
						try {
							out_local.write(cmd.getBytes());
							out_local.flush();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
							localSuccess = false;
						}
					}
				}
			}
		}
	}

	public void sendMqttDataDelay(String buffer) {
		queue_local.add(buffer);
	}

	public void stopLocalTcpClient() {
		try {
			if (in_local != null) {
				in_local.close();// 关闭本地输入流
				in_local = null;
			}
			if (out_local != null) {
				out_local.close(); // 关闭本地输出流
				out_local = null;
			}
			if (socket_local != null) {
				socket_local.close(); // 关闭本地socket连接
				socket_local = null;
			}
			localSuccess = false; // 将连接状态改为未连接
			isStopByUser = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void stopLocalTcpClient1() {
		try {
			if (in_local != null) {
				in_local.close();// 关闭本地输入流
			}
			if (out_local != null) {
				out_local.close(); // 关闭本地输出流
			}
			if (socket_local != null) {
				socket_local.close(); // 关闭本地socket连接
			}
			localSuccess = false; // 将连接状态改为未连接
			// isStopByUser = true;
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// public static String transUDPCmd(String mac, String manufacturer,
	// String productId) {
	// String sendStr = "";
	// JSONObject jo = new JSONObject();
	// JSONObject jo1 = new JSONObject();
	// try {
	// jo.put("a", "20000");
	// jo.put("b", 0);
	// jo.put("c", "20,"+SocketManager.getInstance().user_id);
	// jo.put("d", "10,10000");
	// jo.put("e", 1);
	// jo.put("f", System.currentTimeMillis());
	// jo.put("h", "0.0.1");
	// jo1.put("cmd", 19);
	// jo1.put("manufacturer", manufacturer);
	// jo1.put("productId", productId);
	// jo1.put("mac", mac);
	// jo.put("g", jo1);
	// sendStr = jo.toString();
	// } catch (JSONException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// return sendStr;
	// }

	// public static String transHeartCmd() {
	// String sendStr = "";
	// JSONObject jo = new JSONObject();
	// JSONObject jo1 = new JSONObject();
	// try {
	// jo.put("a", "20000");
	// jo.put("b", 0);
	// jo.put("c", "20," + SocketManager.getInstance().user_id);
	// jo.put("d", "10,10000");
	// jo.put("e", 1);
	// jo.put("f", System.currentTimeMillis());
	// jo.put("h", "0.0.1");
	// jo1.put("cmd", 20);
	// jo.put("g", jo1);
	// sendStr = jo.toString();
	// } catch (JSONException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// return sendStr;
	// }

	public void parseHeartBeat(String data) {
		JSONObject jo = null;
		try {
			jo = new JSONObject(data);
			int cmd = jo.optInt("cmd");
			if (cmd == 20) {
				receiveHeartBeatTime = System.currentTimeMillis();
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void parseData(String recData) {
		receiveHeartBeatTime = System.currentTimeMillis();
		Log.i("wmy", "获取返回数据" + recData);
		JSONObject jo = null;
		JSONObject jo1 = null;
		try {
			jo = new JSONObject(recData);
			String g = jo.optString("g");
			Log.i("wmy", "获取g = " + g);
			jo1 = new JSONObject(g);
			int cmd = jo1.optInt("cmd");
			Log.i("wmy", "获取cmd = " + cmd);
			// 心跳 搜索32 控制RF33 定时 红外64 学习65 温湿度48 记录 升级248 版本242 时间243 校准244
			switch (cmd) {
			case 21:
				int code = jo1.getInt("code");
				if (code == 0) {
					if (listener_Bind != null) {
						listener_Bind.onReceiveData(recData);
					}
				} else {

				}
				break;
			case 20:
				
				break;
			case 32:
				if (listener_Serach != null) {
					listener_Serach.onReceiveData(recData);
				}
				break;
			case 33:

				break;
			case 48:
				if (listener_TempHumity != null) {
					listener_TempHumity.onReceiveData(recData);
				}
				break;
			case 64:

				break;
			case 65:
				if (listener_Study != null) {
					listener_Study.onReceiveData(recData);
				}
				break;
			case 248: // 升级
				if (listener_Update != null) {
					listener_Update.onReceiveData(recData);
				}
				break;
			case 242: // 版本号
				if (listener_Version != null) {
					listener_Version.onReceiveData(recData);
				}
				break;
			default:
				break;
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public int parseTCPPort(String data) {
		// Log.i("wmy", "解析data = " + data);
		int port = 0;
		JSONObject jo = null;
		try {
			jo = new JSONObject(data);
			String g = jo.getString("g");
			JSONObject jo2 = new JSONObject(g);
			Log.i("wmy", "parseTCPPort 解析jo2 = " + jo2.toString());
			port = jo2.getInt("tcp_port");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return port;
	}

	// public interface RecDataCallBackListener {
	// public void onReceiveData(String data);
	// }

	public interface RecDataCallBackListener_Serach {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Version {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Update {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Study {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_TempHumity {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Alarm {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Record {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Time {
		public void onReceiveData(String data);
	}

	public interface RecDataCallBackListener_Bind {
		public void onReceiveData(String data);
	}

	public interface OnConnectSuccessListener {
		public void onReceiveData(String mac);
	}

	public interface OnBindFailListener {
		public void onReceiveData(String mac);
	}

	public interface RecDataCallBackListener_Heart {
		public void onReceiveData(String data);
	}

	// public void setRecDataCallBackListener(RecDataCallBackListener
	// recDataCallBackListener) {
	// this.listener1 = recDataCallBackListener;
	// }

	public void setOnConnectSuccessListener(
			OnConnectSuccessListener onConnectSuccessListener) {
		this.listener_ConnectSuccess = onConnectSuccessListener;
	}

	public void setRecDataCallBackListener_Bind(
			RecDataCallBackListener_Bind recDataCallBackListener_Bind) {
		this.listener_Bind = recDataCallBackListener_Bind;
	}

	public void setRecDataCallBackListener_Heart(
			RecDataCallBackListener_Heart recDataCallBackListener_Heart) {
		this.listener_Heart = recDataCallBackListener_Heart;
	}

	public void setRecDataCallBackListener_Serach(
			RecDataCallBackListener_Serach recDataCallBackListener_Serach) {
		this.listener_Serach = recDataCallBackListener_Serach;
	}

	public void setRecDataCallBackListener_Version(
			RecDataCallBackListener_Version recDataCallBackListener_Version) {
		this.listener_Version = recDataCallBackListener_Version;
	}

	public void setRecDataCallBackListener_Update(
			RecDataCallBackListener_Update recDataCallBackListener_Update) {
		this.listener_Update = recDataCallBackListener_Update;
	}

	public void setRecDataCallBackListener_Study(
			RecDataCallBackListener_Study recDataCallBackListener_Study) {
		this.listener_Study = recDataCallBackListener_Study;
	}

	public void setRecDataCallBackListener_TempHumity(
			RecDataCallBackListener_TempHumity recDataCallBackListener_TempHumity) {
		this.listener_TempHumity = recDataCallBackListener_TempHumity;
	}

	public void setRecDataCallBackListener_Alarm(
			RecDataCallBackListener_Alarm recDataCallBackListener_Alarm) {
		this.listener_Alarm = recDataCallBackListener_Alarm;
	}

	public void setRecDataCallBackListener_Record(
			RecDataCallBackListener_Record recDataCallBackListener_Record) {
		this.listener_Record = recDataCallBackListener_Record;
	}

	public void setRecDataCallBackListener_Time(
			RecDataCallBackListener_Time recDataCallBackListener_Time) {
		this.listener_Time = recDataCallBackListener_Time;
	}
}
